package com.wb.spring.boot.autoconfigure.register;

import com.wb.spring.boot.autoconfigure.constant.SystemConstant;
import com.wb.spring.boot.autoconfigure.exception.RpcException;
import com.wb.spring.boot.autoconfigure.load.Load;
import com.wb.spring.boot.autoconfigure.model.ServerInfo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

public class RedisRegister implements IRegister {

    private final Load load;

    private final RedisTemplate redisTemplate;

    /**
     * 当前服务的信息
     */
    private final ServerInfo serverInfo;

    /**
     * 服务储存体
     */
    private Map<String, HashSet<String>> server = new HashMap();

    @Override
    public void doRegister() {
        redisTemplate.afterPropertiesSet();
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String key = SystemConstant.REDIS_SERVICE_NAME_PREFIX + serverInfo.getServiceName() + "_" + serverInfo.getLocalIp() + ":" + serverInfo.getLocalPort();
        valueOperations.set(key, serverInfo.getLocalIp() + ":" + serverInfo.getLocalPort());
        redisTemplate.expire(key, SystemConstant.REDIS_REGISTER_TIME_OUT, TimeUnit.MILLISECONDS);
        // 发布一个新注册事件
        redisTemplate.convertAndSend(SystemConstant.REDIS_SERVICE_NAME_PREFIX, "register".toCharArray());
    }

    @Override
    public void refreshServer() {
        Map<String, HashSet<String>> newServer = new HashMap();
        Set keys = redisTemplate.keys(SystemConstant.REDIS_SERVICE_NAME_PREFIX + "*");
        if (!CollectionUtils.isEmpty(keys)) {
            ValueOperations valueOperations = redisTemplate.opsForValue();
            for (Object key : keys) {
                String value = (String) valueOperations.get(key);
                String strKey = (String) key;
                strKey = strKey.split("_")[0];
                strKey = strKey.replace(SystemConstant.REDIS_SERVICE_NAME_PREFIX, "");
                if (newServer.containsKey(strKey)) {
                    newServer.get(strKey).add(value);
                } else {
                    HashSet<String> set = new HashSet<>();
                    set.add(value);
                    newServer.put(strKey, set);
                }
            }
        }
        server = newServer;
    }

    @Override
    public String getServer(String serviceName) {
        HashSet<String> strings = server.get(serviceName);
        if (CollectionUtils.isEmpty(strings)) {
            throw new RpcException(serviceName + "不存在提供者, 请检查提供者启动或者配置是否正确。");
        }
        // 通过负载均衡组件获取一个服务，
        return this.load.load(new ArrayList<>(strings));
    }

    @Override
    public void unRegister() {
        String key = SystemConstant.REDIS_SERVICE_NAME_PREFIX + serverInfo.getServiceName() + "_" + serverInfo.getLocalIp() + ":" + serverInfo.getLocalPort();
        redisTemplate.delete(key);
        // 发布一个事件
        redisTemplate.convertAndSend(SystemConstant.REDIS_SERVICE_NAME_PREFIX, "unregister".toCharArray());
    }

    public RedisRegister(RedisTemplate redisTemplate, ServerInfo serverInfo, Load load) {
        this.redisTemplate = redisTemplate;
        this.serverInfo = serverInfo;
        this.load = load;
    }
}
